package com.aplikata.evok.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.event.CloseEvent;
import org.primefaces.model.TreeNode;

import com.aplikata.evok.bo.PatientQtnaire;
import com.aplikata.evok.bo.PatientQtnaireQtInput;
import com.aplikata.evok.bo.PatientTherapy;
import com.aplikata.evok.bo.QtCategory;
import com.aplikata.evok.bo.Qtnaire;
import com.aplikata.evok.bo.Result;
import com.aplikata.evok.constants.EvokConstants;
import com.aplikata.evok.datamodel.PatientQtnaireDataModel;
import com.aplikata.evok.service.EvokQtnaireService;
import com.aplikata.ui.UIBean;
import com.aplikata.util.FacesUtil;
import com.aplikata.util.ListUtil;
import com.aplikata.util.NReflection;

@ManagedBean(name = "evokPatientQtnaireBean")
@ViewScoped
public class EvokPatientQtnaireBean extends UIBean {

	private static final long serialVersionUID = 1L;

	@ManagedProperty(value = "#{evokQtnaireService}")
	protected EvokQtnaireService evokQtnaireService;

	protected PatientTherapy patientTherapy;
	protected PatientQtnaire patientQtnaire;
	protected TreeNode rootQtnaire;
	protected TreeNode selectedNode;
	private PatientQtnaireDataModel patientQtnaireModel;

	protected Object refobj;

	protected List<PatientQtnaireQtInput> questions;

	private Map<Long, List<?>> resultSelectMap;

	private int tabIndex;

	@PostConstruct
	public void init() {
		patientTherapy = new PatientTherapy(getSessionUser());
	}

	public void qtnaireAddAction() {
		if (patientTherapy == null || FacesUtil.isKeyNull(patientTherapy.getId())) {
			FacesUtil.addErrorMessage(FacesUtil.getMessage("patient_qtnaire_ptherapy_empty"));
			return;
		}
		if (selectedNode == null) {
			return;
		}
		Object obj = selectedNode.getData();
		if (obj instanceof Qtnaire) {
			Qtnaire qtnaire = (Qtnaire) obj;
			addPatientQtnaire(qtnaire);
		}
		questions = null;
		resultSelectMap = null;
	}

	private void addPatientQtnaire(Qtnaire qtnaire) {
		qtnaire = (Qtnaire) evokQtnaireService.get(Qtnaire.class, qtnaire.getId());
		patientQtnaire = new PatientQtnaire(FacesUtil.getUserFromSession(), patientTherapy, qtnaire);
	}

	public void editAction(ActionEvent event) {
		questions = null;
		resultSelectMap = null;
	}

	public void deleteListenerAction(ActionEvent event) {
		questions = new ArrayList<PatientQtnaireQtInput>();
	}
	
	public void handleClose(CloseEvent event) { 
		patientQtnaire = null;
	}

	public void resetQueryAction(ActionEvent event) {
		patientQtnaire = null;
	}

	public void submitAction() {
		try {
			patientQtnaire = evokQtnaireService.updatePatientQtnaire(patientQtnaire, questions);
			FacesUtil.addInfoMessage("patient_qtnaire_update_success");
			patientQtnaire = null;
			populatePatientQtnaireModel();
			tabIndex = 0;
		} catch (Exception e) {
			FacesUtil.addActionException(e, log);
		}
	}

	public void deleteAction() {
		if (patientQtnaire == null || FacesUtil.isKeyNull(patientQtnaire.getId())) {
			FacesUtil.addErrorMessage(FacesUtil.getMessage("qtnaire_qtpt_empty"));
			return;
		}
		try {
			evokQtnaireService.deletePatientQtnaire(patientQtnaire);
			patientQtnaire = null;
			populatePatientQtnaireModel();
			FacesUtil.addInfoMessage("patient_qtnaire_delete_success");
			tabIndex = 0;
		} catch (Exception e) {
			FacesUtil.addActionException(e, log);
		}
	}

	protected String populateReflectionAction(PatientQtnaire patientQtnaire) throws Exception {
		NReflection ref = new NReflection();
		refobj = ref.newInstance(patientQtnaire.getQtnaire().getBeanName(), null);
		ref.invokeSetMethod(refobj, "evokQtnaireService", EvokQtnaireService.class, evokQtnaireService);
		ref.invokeSetMethod(refobj, "patientQtnaire", PatientQtnaire.class, patientQtnaire);
		ref.invokeMethod(refobj, "paintChart", new Object[] {});

		return "graph";
	}

	public EvokQtnaireService getEvokQtnaireService() {
		return evokQtnaireService;
	}

	public void setEvokQtnaireService(EvokQtnaireService evokQtnaireService) {
		this.evokQtnaireService = evokQtnaireService;
	}

	public PatientQtnaire getPatientQtnaire() {
		return patientQtnaire;
	}

	public void setPatientQtnaire(PatientQtnaire patientQtnaire) {
		this.patientQtnaire = patientQtnaire;
	}

	public TreeNode getSelectedNode() {
		return selectedNode;
	}

	public void setSelectedNode(TreeNode selectedNode) {
		this.selectedNode = selectedNode;
	}

	@SuppressWarnings("unchecked")
	public List<PatientQtnaireQtInput> getQuestions() {
		if (patientQtnaire == null || patientQtnaire.getQtnaire() == null
				|| FacesUtil.isKeyNull(patientQtnaire.getQtnaire().getId()))
			return null;

		if (questions != null)
			return questions;

		questions = (List<PatientQtnaireQtInput>) evokQtnaireService.getPatientQuestionList(patientQtnaire);

		return questions;
	}

	public void setQuestions(List<PatientQtnaireQtInput> questions) {
		this.questions = questions;
	}

	@SuppressWarnings({ "unchecked" })
	public Map<Long, List<?>> getResultSelectMap() {
		if (resultSelectMap == null && patientQtnaire != null) {
			resultSelectMap = new HashMap<Long, List<?>>();
			List<QtCategory> qtCategoryList = (List<QtCategory>) evokQtnaireService.findByNamedQuery(
					QtCategory.QY_FIND_BY_QTNAIRE, new Object[] { patientQtnaire.getQtnaire().getId() });
			for (QtCategory oneCategory : qtCategoryList) {
				Result oneResult = oneCategory.getResult();
				resultSelectMap.put(oneCategory.getId(), null);
				if (oneResult != null) {
					resultSelectMap.put(oneCategory.getId(), ListUtil.convertToList(oneResult.getResultDetails()));
				}
			}

		}
		return resultSelectMap;
	}

	public void setResultSelectMap(Map<Long, List<?>> resultSelectMap) {
		this.resultSelectMap = resultSelectMap;
	}

	public Object getRefobj() {
		return refobj;
	}

	public void setRefobj(Object refobj) {
		this.refobj = refobj;
	}

	public TreeNode getRootQtnaire() {
		if (rootQtnaire == null) {
			rootQtnaire = evokQtnaireService.getRootQtnairePatient(FacesUtil.getUserFromSession().getRole());
		}
		return rootQtnaire;
	}

	public void setRootQtnaire(TreeNode rootQtnaire) {
		this.rootQtnaire = rootQtnaire;
	}

	public PatientTherapy getPatientTherapy() {
		if (FacesContext.getCurrentInstance().getExternalContext().getFlash()
				.containsKey(EvokConstants.FLASH_PATIENT_THERAPY)) {
			patientTherapy = (PatientTherapy) FacesContext.getCurrentInstance().getExternalContext().getFlash()
					.get(EvokConstants.FLASH_PATIENT_THERAPY);
			populatePatientQtnaireModel();
		}
		return patientTherapy;
	}

	@SuppressWarnings("unchecked")
	public void populatePatientQtnaireModel() {
		if (patientTherapy == null)
			return;
		List<PatientQtnaire> qtnaireList = (List<PatientQtnaire>) evokQtnaireService.findByNamedQuery(
				PatientQtnaire.QY_FIND_BY_THERAPY, new Object[] { patientTherapy.getId() });
		if (patientQtnaireModel == null)
			patientQtnaireModel = new PatientQtnaireDataModel(evokQtnaireService, qtnaireList);
		else
			patientQtnaireModel.setWrappedData(qtnaireList);
	}

	public void setPatientTherapy(PatientTherapy patientTherapy) {
		this.patientTherapy = patientTherapy;
	}

	public PatientQtnaireDataModel getPatientQtnaireModel() {
		return patientQtnaireModel;
	}

	public void setPatientQtnaireModel(PatientQtnaireDataModel patientQtnaireModel) {
		this.patientQtnaireModel = patientQtnaireModel;
	}

	public int getTabIndex() {
		return tabIndex;
	}

	public void setTabIndex(int tabIndex) {
		this.tabIndex = tabIndex;
	}
}
